🔧 Step 7: Shared Module – Low Level Design (LLD)
This document details the implementation of the shared module, which provides common UI components, directives, and pipes used throughout the app.
📦 Module Structure
src/
├── app/
│ └── shared/
│ ├── components/
│ │ ├── button/
│ │ ├── modal/
│ │ ├── loader/
│ │ └── snackbar/
│ ├── directives/
│ │ ├── autofocus.directive.ts
│ │ └── permission.directive.ts
│ ├── pipes/
│ │ ├── currency-format.pipe.ts
│ │ └── truncate.pipe.ts
│ ├── services/
│ │ └── snackbar.service.ts
│ ├── shared.module.ts
🧱 Component Breakdown
🔘 ButtonComponent
- Reusable button with configurable styles (primary, secondary, disabled states)
- Emits click events to parent components
🗔 ModalComponent
- Generic modal dialog component with customizable header, body, footer slots
- Supports close/cancel actions
⏳ LoaderComponent
- Displays a loading spinner overlay
- Used to indicate asynchronous operations in progress
🔔 SnackbarComponent
- Shows brief toast/snackbar messages for feedback (success, error, info)
- Auto-dismisses after timeout or on user action
⚙️ Directives
🔍 AutofocusDirective
- Automatically sets focus to an input element when the component loads
🔐 PermissionDirective
- Conditionally shows/hides elements based on user permissions or roles
🔄 Pipes
💰 CurrencyFormatPipe
- Formats numeric values as localized currency strings
✂️ TruncatePipe
- Truncates long text strings and appends ellipsis (
…) for UI consistency
🧪 Services
SnackbarService
- Controls display of snackbars across the app
- Provides methods to show success, error, and info messages
@Injectable({ providedIn: "root" })
export class SnackbarService {
private snackbarSubject = new Subject<SnackbarMessage>();
get messages$(): Observable<SnackbarMessage> {
return this.snackbarSubject.asObservable();
}
showSuccess(message: string): void {
this.snackbarSubject.next({ message, type: "success" });
}
showError(message: string): void {
this.snackbarSubject.next({ message, type: "error" });
}
showInfo(message: string): void {
this.snackbarSubject.next({ message, type: "info" });
}
}
export interface SnackbarMessage {
message: string;
type: "success" | "error" | "info";
}
📐 Module Definition
@NgModule({
declarations: [
ButtonComponent,
ModalComponent,
LoaderComponent,
SnackbarComponent,
AutofocusDirective,
PermissionDirective,
CurrencyFormatPipe,
TruncatePipe,
],
imports: [CommonModule],
exports: [
ButtonComponent,
ModalComponent,
LoaderComponent,
SnackbarComponent,
AutofocusDirective,
PermissionDirective,
CurrencyFormatPipe,
TruncatePipe,
],
})
export class SharedModule {}
✅ Responsibilities Summary
| Part | Responsibility |
|---|---|
| ButtonComponent | Reusable button UI |
| ModalComponent | Generic modal dialogs |
| LoaderComponent | Loading indicators |
| SnackbarComponent | Toast/snackbar feedback |
| AutofocusDirective | Auto-focus inputs |
| PermissionDirective | Conditional UI rendering based on permissions |
| CurrencyFormatPipe | Currency formatting |
| TruncatePipe | Text truncation |
| SnackbarService | Centralized snackbar management |